package leveldb

import (
	"ant-agent/pkg/logger"
	"encoding/json"
	"fmt"
	"time"

	cache "github.com/patrickmn/go-cache"
)

const (
	// For use with functions that take an expiration time.
	NoExpiration time.Duration = -1
	// For use with functions that take an expiration time. Equivalent to
	// passing in the same expiration duration as was given to New() or
	// NewFrom() when the cache was created (e.g. 5 minutes.)

	CleanupInterval = 20 * time.Minute
)

type DBService struct {
	Cache *cache.Cache
	DB    Goleveldb
}

func NewDBCache() (*DBService, error) {
	return newCache(NoExpiration, CleanupInterval)
}

func newCache(defaultExpiration time.Duration, cleanupInterval time.Duration) (*DBService, error) {
	c := cache.New(defaultExpiration, cleanupInterval)
	db, err := Open()
	if err != nil {
		logger.Error("open db err:%v", err)
		return nil, err
	}
	Cache := &DBService{
		Cache: c,
		DB:    db,
	}
	return Cache, nil
}

func (s *DBService) SetNoExpiration(msgType int, key string, value interface{}) error {
	dbObj, err := json.Marshal(value)
	if err != nil {
		return err
	}
	err = s.DB.Put(key, dbObj)
	if err != nil {
		logger.Error("db put err:%v", err)
		return err
	}
	s.Cache.Set(key, value, NoExpiration)
	return nil
}

func (s *DBService) LoadMsgFromDB(key string, value interface{}) error {
	v, err := s.DB.Get(key)
	if err != nil {
		return err
	}
	if len(v) == 0 {
		return fmt.Errorf("not find records")
	}
	return json.Unmarshal(v, &value)
}

func (s *DBService) Delete(key string) {
	s.Cache.Delete(key)
	s.DB.Delete(key)
}

func (s *DBService) Release() error {
	return s.DB.Close()
}

func (s *DBService) Put(key string, value interface{}) error {
	dbObj, err := json.Marshal(value)
	if err != nil {
		return err
	}
	return s.DB.Put(key, dbObj)
}
